import java.util.concurrent.CompletableFuture;
import java.util.function.Supplier;

public class Test {
        public static void main(String[] args) throws Exception {
                // CompletableFuture_test();
                // CompletableFuture_thenappplay_test();
                // CompletableFuture_anyof_test();
                CompletableFuture_allof_test();
        }

        public static void CompletableFuture_test() throws Exception {
                // CompletableFuture，它针对Future做了改进，可以传入回调对象，当异步任务完成或者发生异常时，自动调用回调对象的回调方法
                Supplier<Integer> s1 = () -> {
                        try {
                                Thread.sleep(1000);

                        } catch (Exception e) {
                                e.printStackTrace();
                        }
                        if (Math.random() > 0.7) {
                                throw new RuntimeException("some exception happend!");
                        } else {
                                return 233;
                        }
                };
                CompletableFuture<Integer> promise = CompletableFuture.supplyAsync(s1);
                // 如果执行成功:
                promise.thenAccept((result) -> {
                        System.out.println("price: " + result);
                });
                // 如果执行异常:
                promise.exceptionally((e) -> {
                        e.printStackTrace();
                        return null;
                });
                Thread.sleep(2000);
        }

        // 链式调用
        @SuppressWarnings("deprecation")
        public static void CompletableFuture_thenappplay_test() throws Exception {

                CompletableFuture<Integer> promise = CompletableFuture.supplyAsync(() -> {
                        System.out.println("promise 当前线程名称 " + Thread.currentThread().getId());
                        return 1;
                });
                // thenApply → 回调线程 = 前面任务完成的线程（同步回调）
                CompletableFuture<Integer> promise2 = promise.thenApply(res -> {
                        System.out.println("promise2 当前线程名称 " + Thread.currentThread().getId());
                        return res + 1;
                });
                // thenApplyAsync → 回调线程 = 线程池重新调度（异步回调）
                CompletableFuture<Integer> promise3 = promise2.thenApplyAsync(res -> {
                        System.out.println("promise3 当前线程名称 " + Thread.currentThread().getId());
                        return res + 1;
                });
                promise3.thenAccept(res -> System.out.println(res));
                promise3.exceptionally(e -> {
                        e.printStackTrace();
                        return null;

                });
                promise3.join(); // 阻塞直到整条链完成

        }

        // promise.race
        public static void CompletableFuture_anyof_test() throws Exception {

                CompletableFuture<Integer> promise = CompletableFuture.supplyAsync(() -> {
                        try {
                                Thread.sleep(300);
                        } catch (Exception e) {
                                e.printStackTrace();
                        }
                        return 1;
                });
                CompletableFuture<Integer> promise2 = CompletableFuture.supplyAsync(() -> {
                        try {
                                Thread.sleep(200);
                        } catch (Exception e) {
                                e.printStackTrace();
                        }
                        return 2;
                });
                CompletableFuture<Object> promise3 = CompletableFuture.anyOf(promise, promise2);
                promise3.thenAccept(res -> System.out.println(res));
                promise3.exceptionally(e -> {
                        e.printStackTrace();
                        return null;

                });
                promise3.join();

        }

        // promise.all
        public static void CompletableFuture_allof_test() throws Exception {

                CompletableFuture<Integer> promise = CompletableFuture.supplyAsync(() -> {
                        try {
                                Thread.sleep(300);
                        } catch (Exception e) {
                                e.printStackTrace();
                        }
                        return 1;
                });
                CompletableFuture<Integer> promise2 = CompletableFuture.supplyAsync(() -> {
                        try {
                                Thread.sleep(200);
                        } catch (Exception e) {
                                e.printStackTrace();
                        }
                        return 2;
                });
                // allOf 只发“完成信号”，结果要自己再去找各个原始 Future 要！
                // CompletableFuture.allOf(promise, promise2);只会等待完成不会消费
                CompletableFuture<Void> promise3 = CompletableFuture.allOf(promise, promise2);
                // thenRun：不要结果，只干活
                promise3.thenRun(() -> {
                        try {
                                System.out.println("promise's result is " + promise.get());
                                System.out.println("promise2's result is " + promise2.get());
                        } catch (Exception e) {
                                e.printStackTrace();
                        }
                });
                promise3.exceptionally(e -> {
                        e.printStackTrace();
                        return null;

                });
                promise3.join(); // 阻塞直到整条链完成

        }
}